package com.jg.poiet.excel;

import com.jg.poiet.excel.po.ICell;
import com.jg.poiet.excel.po.IRow;
import com.jg.poiet.excel.po.ISheet;
import com.jg.poiet.excel.po.IWorkBook;
import com.jg.poiet.exception.ExcelException;
import com.jg.poiet.exception.WordException;
import com.jg.poiet.util.DateUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.File;
import java.io.FileInputStream;
import java.util.Date;
import java.util.List;

public abstract class NiceExcel {

    private List<List<Object>> dataList;
    private int rowSize;
    private int colSize;

    public static NiceExcel compile(String path) {
        return compile(new File(path));
    }

    public static NiceExcel compile(File file) {
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(file);
            try {
                HSSFWorkbook workbook = new HSSFWorkbook(fis);
                return new HSSFNiceExcel(workbook);
            } catch (Exception ignore) {
                try {
                    fis.close();
                } catch (Exception ignore1) {}
                fis = new FileInputStream(file);
                try {
                    XSSFWorkbook workbook = new XSSFWorkbook(fis);
                    return new XSSFNiceExcel(workbook);
                } catch (Exception e) {
                    e.printStackTrace();
                    throw new ExcelException("暂不支持当前文件！");
                }
            }
        } catch (Exception e) {
            throw new ExcelException("文件不存在！");
        } finally {
            if (fis != null) {
                try {
                    fis.close();
                } catch (Exception ignore) {}
            }
        }
    }

    /**
     * 设置所有数据
     */
    protected void setAllData(List<List<Object>> dataList) {
        this.dataList = dataList;
        this.rowSize = dataList.size();
        for (List<Object> data : dataList) {
            if (data.size() > this.colSize) {
                this.colSize = data.size();
            }
        }
    }

    /**
     * 获取所有数据
     */
    public List<List<Object>> getAllData() {
        return dataList;
    }

    /**
     * 行数
     */
    public int getRowSize() {
        return rowSize;
    }

    /**
     * 列数
     */
    public int getColSize() {
        return colSize;
    }

    /**
     * 获取表格字符串类型值
     * @param row 行 从0开始
     * @param col 列 从0开始
     * @param defaultValue 默认值
     * @return 字符串类型值
     */
    public String getStrValue(int row, int col, String defaultValue) {
        if (dataList.size() <= row) {
            return defaultValue;
        }
        List<Object> data = dataList.get(row);
        if (data.size() <= col) {
            return defaultValue;
        }
        Object obj = data.get(col);
        if (obj == null) {
            return defaultValue;
        }
        return obj.toString();
    }

    /**
     * 获取字符串类型值
     * @param row 行
     * @param col 列
     * @return 值
     */
    public String getStrValue(int row, int col) {
        return getStrValue(row, col, "");
    }

    /**
     * 获取双精度类型值
     * @param row 行
     * @param col 列
     * @return 值
     */
    public Double getDoubleValue(int row, int col) {
        String value = getStrValue(row, col);
        if ("".equals(value)) {
            return null;
        }
        return Double.valueOf(value);
    }

    /**
     * 获取长整型类型值
     * @param row 行
     * @param col 列
     * @return 值
     */
    public Long getLongValue(int row, int col) {
        String value = getStrValue(row, col);
        if ("".equals(value)) {
            return null;
        }
        return Long.valueOf(value);
    }

    /**
     * 获取整型类型值
     * @param row 行
     * @param col 列
     * @return 值
     */
    public Integer getIntegerValue(int row, int col) {
        String value = getStrValue(row, col);
        if ("".equals(value)) {
            return null;
        }
        return Integer.valueOf(value);
    }

    /**
     * 获取日期类型值
     * @param row 行
     * @param col 列
     * @return 值
     */
    public Date getDateValue(int row, int col) {
        String value = getStrValue(row, col);
        if ("".equals(value)) {
            return null;
        }
        return DateUtils.parseDate(value);
    }

    /**
     * 转换成html格式
     */
    public String toHtml() {
        IWorkBook workBook = parseExcel();
        StringBuilder res = new StringBuilder();
        res.append("<html>");
        res.append("<head>");
        res.append("<style>");
        res.append(".sheetTitle { font-size: 18px;font-weight: bold;text-align: center;line-height: 40px; }");
        res.append(".tableContainer { max-width: 100%;overflow: auto;border: 1px solid black;padding: 8px; }");
        res.append("table { border-collapse: collapse; }");
        res.append("td { margin: 0; padding: 0; }");
        res.append("</style>");
        res.append("</head>");
        res.append("<body>");
        for (ISheet sheet : workBook.getSheetList()) {
            res.append("<div class=\"sheetTitle\">").append(sheet.getName()).append("</div>");
            if (sheet.getRowList().size() == 0) {
                continue;
            }
            res.append("<div class=\"tableContainer\">");
            res.append("<table border=\"0\"><tbody>");
            for (IRow row : sheet.getRowList()) {
                res.append("<tr>");
                if (row.getCellList().size() > 0) {
                    for (int i = 0; i < sheet.getMaxCellNums(); i++) {
                        if (i < row.getCellList().size()) {
                            ICell cell = row.getCellList().get(i);
                            if (cell.existsCell()) {
                                res.append("<td colspan=\"" + cell.getColSpan() + "\" rowspan=\""
                                        + cell.getRowSpan() + "\" style=\"");
                                if (cell.getLeftBorderColor() != null) {
                                    res.append("border-left: 1px solid #" + cell.getLeftBorderColor() + ";");
                                }
                                if (cell.getRightBorderColor() != null) {
                                    res.append("border-right: 1px solid #" + cell.getRightBorderColor() + ";");
                                }
                                if (cell.getTopBorderColor() != null) {
                                    res.append("border-top: 1px solid #" + cell.getTopBorderColor() + ";");
                                }
                                if (cell.getBottomBorderColor() != null) {
                                    res.append("border-bottom: 1px solid #" + cell.getBottomBorderColor() + ";");
                                }
                                res.append("color: #" + cell.getFontColor() + ";");
                                res.append("font-size: " + cell.getFontSize() + "px;");
                                if (cell.isBold()) {
                                    res.append("font-weight: bold;");
                                }
                                res.append("\">");
                                res.append("<div style=\"display:flex; width: "
                                        + cell.getWidth() + "px;height: " + cell.getHeight() + "px;");
                                if (cell.getBackgroundColor() != null) {
                                    res.append("background-color: #" + cell.getBackgroundColor() + ";");
                                }
                                res.append("justify-content: ").append(cell.getHorizontalAlignment()).append(";");
                                res.append("align-items: ").append(cell.getVerticalAlignment()).append(";");
                                res.append("\">");
                                res.append(cell.getValue());
                                res.append("</div>");
                                res.append("</td>");
                            }
                        } else {
                            res.append("<td style=\" \"></td>");
                        }
                    }
                } else {
                    for (int i = 0; i < sheet.getMaxCellNums(); i++) {
                        res.append("<td style=\" height: 20px; \"></td>");
                    }
                }
                res.append("</tr>");
            }
            res.append("</tbody></table>");
            res.append("</div>");
        }
        res.append("</body>");
        res.append("</html>");
        return res.toString();
    }

    /**
     * 解析excel
     */
    public abstract IWorkBook parseExcel();

}
